package com.gopay.bis.manager.bank.ebank;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.TransUtil;
import com.gopay.bis.dao.payconfig.BisBankExtConfigDAO;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.ipay.ebank.IpayMessage;
import com.gopay.common.domain.bis.BaseBisBankExtConfig;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.BankManagerRemoteService;
import com.gopay.remote.bank.businesses.BankService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 民生i支付对象封装
 * 
 * @IpayManager.java
 * @author lilili
 * @2016年7月8日 下午1:46:09 www.gopay.com.cn Inc.All rights reserved.
 */
public class IpayManager implements BankManagerRemoteService {
	
	private static Logger logger = LoggerFactory.getLogger(IpayManager.class);
	

	@Resource(name = "iPayConfig")
	private Map<String, String> iPayConfig;

	@Resource(name = "iPayBankServiceClient")
	private BankService iPayBankServiceClient;

	@Resource(name = "bisBankExtConfigDAO")
	private BisBankExtConfigDAO bisBankExtConfigDAO;

	@Override
	public Object sign(BaseMessage msg) throws GopayException {
		// 获取银行接口通道配置信息
//		BaseBisBankExtConfig bankConfig = bisBankExtConfigDAO
//				.findExtConfigByBankCodeAndBankBusProd(msg.getBankBusProd(), msg.getBank());
		msg.setBankOrderId("IP" + TransUtil.processOrderIdTo14Digit(msg.getOrderId()));
		// 设置民生i支付接口银行码
		//msg.setSpecial2(bankConfig.getIntrfaceBankCode());
	    IpayMessage message = (IpayMessage)msg;
	    message.setOidPartner(iPayConfig.get("IPAY.OLDPARTNER"));
	    message.setUserId(message.getSpecial2());
	    message.setNoOrder(message.getBankOrderId());
	    message.setNameGoods(iPayConfig.get("IPAY.GOODSNAME"));
	    message.setNotifyUrl(iPayConfig.get("IPAY.NOTIFYURL"));
	    message.setUrlReturn(iPayConfig.get("IPAY.RETURNURL"));
	    message.setDtOrder(message.getOrderDate());
	    message.setMoneyOrder(message.getAmount().toString());
	    if(msg.getBank().equals(BankConstants.BANK_LOGO_CMBC)){
            message.setBankCode(iPayConfig.get("IPAY.CMBC.BANKCODE"));
            //民生银行单独上传
             message.setPayType("1");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_CCB)){
            message.setBankCode(iPayConfig.get("IPAY.CCB.BANKCODE"));
            message.setPayType("1");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_ABC)){
            message.setBankCode(iPayConfig.get("IPAY.ABC.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_BOC)){
            message.setBankCode(iPayConfig.get("IPAY.BOC.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_ICBC)){
            message.setBankCode(iPayConfig.get("IPAY.ICBC.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_CMB)){
            message.setBankCode(iPayConfig.get("IPAY.CMB.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_BOCOM)){
            message.setBankCode(iPayConfig.get("IPAY.BOCOM.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_CIB)){
            message.setBankCode(iPayConfig.get("IPAY.CIB.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_CITIC)){
            message.setBankCode(iPayConfig.get("IPAY.CITIC.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_SPDB)){
            message.setBankCode(iPayConfig.get("IPAY.SPDB.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_GDB)){
            message.setBankCode(iPayConfig.get("IPAY.GDB.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_PAB)){
            message.setBankCode(iPayConfig.get("IPAY.PAB.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_CEB)){
            message.setBankCode(iPayConfig.get("IPAY.CEB.BANKCODE"));
            message.setPayType("3");
        }else if(msg.getBank().equals(BankConstants.BANK_LOGO_HXBC)){
            message.setBankCode(iPayConfig.get("IPAY.HXBC.BANKCODE"));
            message.setPayType("1");
        }else{
            message.setPayType("3");
        }
	    message.setOutStlmCd("IPAY"); 
	    message.setPlainMessage(getPayPlain(message).toString());
	    BankLogUtils.printB2CManagerSignSendLog(message);
	   
        message = (IpayMessage)iPayBankServiceClient.sign(message);  
        
        BankLogUtils.printB2CManagerSignReturnLog(message);
		return message;
	}

    @Override
    public Object refund(BaseMessage base) throws GopayException {
        IpayMessage message = (IpayMessage) base;
        message.setOidPartner(iPayConfig.get("IPAY.OLDPARTNER"));
        message.setNoOrder(message.getBankOrderId());
        message.setDtOrder(message.getOrderDate());
        message.setMoneyOrder(message.getAmount().toString());
        message.setOriNoOrder(message.getTkOriBankOrderId()); // 原交易银行订单号
        message.setNotifyUrl(iPayConfig.get("IPAY.REFUND.NOTIFYURL"));
        message.setPlainMessage(getRefundPlain(message).toString());
        BankLogUtils.printRefundManagerSendLog(message);

        message = (IpayMessage) iPayBankServiceClient.refund(message);
       
        BankLogUtils.printRefundManagerReturnLog(message);
        return message;
    }
	
	@Override
	public Object verify(BaseMessage msg) throws GopayException {
		   IpayMessage message = (IpayMessage)msg;
	        String plainMessage = getVerifyPlain(message).toString();
	        message.setPlainMessage(plainMessage);
	        BankLogUtils.printB2CManagerVerifySendLog(message);
	       boolean isVeirfy=(Boolean) iPayBankServiceClient.verify(message);  
	        BankLogUtils.printB2CManagerVerifyReturnLog(message,"");
	        return isVeirfy;
	}

	@Override
	public Object dayend(BaseMessage msg) throws GopayException {
		IpayMessage message = (IpayMessage) msg;
		message.setOidPartner(iPayConfig.get("IPAY.OLDPARTNER"));
		message.setPlainMessage(getBillPlain(message).toString());
		BankLogUtils.printB2CManagerDayendReqLog(message);
		Object res = iPayBankServiceClient.dayend(message);
		BankLogUtils.printB2CManagerDayendReturnLog(message);
		return res;
	}

	@Override
    public Object query(Object msg) throws GopayException {
        IpayMessage message = (IpayMessage) msg;
        message.setOidPartner(iPayConfig.get("IPAY.OLDPARTNER"));
        message.setNoOrder(message.getBankOrderId());
        message.setDtOrder(message.getOrderDate());
        message.setOriNoOrder(message.getBankOrderId());
        message.setPlainMessage(getQueryPlain(message).toString());
        BankLogUtils.printB2CManagerQuerySendLog(message, message);

        message = (IpayMessage) iPayBankServiceClient.query(message);

        BankLogUtils.printB2CManagerQueryReturnLog(message);
        return message;
    }
	public Object getBillPlain(BaseMessage msg){
		IpayMessage message = (IpayMessage) msg;
		StringBuffer sb = new StringBuffer();
		sb.append("oid_partner=").append(message.getOidPartner()).append("&");
		sb.append("settle_date=").append(message.getSettleDate());
		return sb.toString();
	}
	
	/**
     * 支付报文组装
     * @param msg
     * @return
     */
    public Object getPayPlain(BaseMessage msg){
        IpayMessage message = (IpayMessage) msg;
        HashMap<String, String> data = new HashMap<String, String>();  
        
        data.put("bank_code", message.getBankCode());
        data.put("oid_partner", message.getOidPartner());
        data.put("user_id", message.getUserId());
        data.put("no_order", message.getNoOrder());
        data.put("dt_order", message.getDtOrder());
        data.put("name_goods", message.getNameGoods());
        data.put("money_order", message.getMoneyOrder());
        data.put("notify_url", message.getNotifyUrl());
        data.put("url_return", message.getUrlReturn());
        data.put("pay_type", message.getPayType());
     
        String plain="";
		try {
			plain = getPlainText(data);
			logger.error("------ipay manager pay plain-----"+plain);
		} catch (UnsupportedEncodingException e) {
			logger.error("------ipay manager getPayPlain error-----"+e.getMessage());
			
		}
        return plain;
    }
    
    /**
     * 退款报文组装
     * 
     * @param msg
     * @return
     */
    public Object getRefundPlain(BaseMessage msg) {
        IpayMessage message = (IpayMessage) msg;
        StringBuffer sb = new StringBuffer();
        sb.append("dt_order=").append(message.getDtOrder()).append("&");
        sb.append("money_order=").append(message.getMoneyOrder()).append("&");
        sb.append("no_order=").append(message.getNoOrder()).append("&");
        sb.append("notify_url=").append(message.getNotifyUrl()).append("&");
        sb.append("oid_partner=").append(message.getOidPartner()).append("&");
        sb.append("ori_no_order=").append(message.getOriNoOrder());
        String plain = sb.toString();

        return plain;
    }
	
	/**
	 * 通知返回报文组装
	 * @param msg
	 * @return
	 */
	public Object getVerifyPlain(BaseMessage msg){
		IpayMessage message = (IpayMessage) msg;
        HashMap<String, String> data = new HashMap<String, String>();  
	       
        data.put("oid_partner", message.getOidPartner());
        data.put("no_order", message.getNoOrder());
        data.put("money_order", message.getMoneyOrder());
        data.put("pay_type", message.getPayType());
        data.put("oid_paybill", message.getOidPaybill());
        data.put("resp_type", message.getRespType());
        data.put("resp_code", message.getRespCode());
        data.put("resp_msg", message.getRespMsg());
        data.put("settle_date", message.getSettleDate());
     
        String plain="";
		try {
			plain = getPlainText(data);
			logger.error("------ipay manager verify plain-----"+plain);
		} catch (UnsupportedEncodingException e) {
			logger.error("------ipay manager getVerifyPlain error-----"+e.getMessage());
			
		}
        return plain;
	}

	
    /**
     * 查询报文组装
     * 
     * @param msg
     * @return
     */
    public Object getQueryPlain(BaseMessage msg) {
        IpayMessage message = (IpayMessage) msg;
        StringBuffer sb = new StringBuffer();
        sb.append("dt_order=").append(message.getOrderDate()).append("&");
        sb.append("no_order=").append(message.getNoOrder()).append("&");
        sb.append("oid_partner=").append(message.getOidPartner()).append("&");
        sb.append("ori_no_order=").append(message.getOriNoOrder());
        String plain = sb.toString();

        return plain;
    }

    
    /**
     * 生成待签名串
     * 
     * @param paramMap
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String getPlainText(Map<String, String> params) throws UnsupportedEncodingException {
        StringBuffer content = new StringBuffer();
        // 按照key做首字母升序排列
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
        for (int i = 0; i < keys.size(); i++) {
            String key = (String) keys.get(i);
            if ("sign".equals(key)) {
                continue;
            }
            String value = params.get(key);
            // 空串不参与签名
            if (isnull(value)) {
                continue;
            }
            content.append((i == 0 ? "" : "&") + key + "=" + value);

        }
        String signSrc = content.toString();
        if (signSrc.startsWith("&")) {
            signSrc = signSrc.replaceFirst("&", "");
        }
        return signSrc;
    }

    /**
     * str空判断
     * 
     * @param str
     * @return
     */
    public static boolean isnull(String str) {
        if (null == str || str.equalsIgnoreCase("null") || str.trim().equals("")) {
            return true;
        } else
            return false;
    }

}
